/** 
* @file        zos_main.c
* @ingroup     zos_main
* @brief       
*/
/**
 * @defgroup zos main
 */
#include "zos.h"
#include "cmiot.h"
#include "zos_config.h"

//任务全局变量
zos_task_t user_main_task_Handle = NULL;

zos_task_t uart2_Handle = NULL;
zos_task_t send_uart_cmd_Handle = NULL;
zos_sem_t notify_sem1 = ZOS_NULL;

float sum = 0.0;
float cur = 0.0;

extern cmiot_stream_t sum_object;
extern cmiot_stream_t cur_object;

//如果在 user_main_task 任务里面进行复杂程序，请将任务的栈改大一些
#define USER_MAIN_STACK_SIZE       1024

// 读取串口数据的时间间隔，默认60s
#define SEND_INTERVAL  1 * 60

void user_main_task(void *parameter)
{
	struct nb_time_t mtime;
	zos_uint32_t msec = 0;
	zos_uint32_t sec = 0;
	int i=0,cgact;
	char *str=zos_zalloc(100);
	zos_printf("Hello, welcome to using QS-100 module. The ZeusOS-SDK integrates shell functions. You can send help and other commands to operate the module.\r\n");
	zos_printf("Hello, ZeusOS 2.2\r\n");
	
//*****  上电检测是否来自深睡眠唤醒  *****//
	
	if(nb_get_powenon_from_deepsleep() != ZOS_EOK)
	{
		//如果属于正常开机，需要执行连网操作
		if(network_init() == ZOS_ERROR)
		{
			//模块连接到网络失败，等待20S，然后重启模组
			zos_task_delay(20000);
			zos_reboot();
		}
		//关闭PSM模式
		// nb_close_psm();

		//关闭EDRX模式
		// nb_close_edrx();

		//设置edrx参数
		//nb_set_edrx("0011","0011");
		
		//获取NB卡的APN
		nb_get_PDP_APN(str,100,0);
		zos_printf("APN=%s\r\n",str);
		nb_get_VERSIONEXT(str,30);
		zos_printf("version=%s\r\n",str);
		zos_free(str);
	}
	
//*****  模块来自深睡眠唤醒或者模块联网成功后执行的操作  *****//

	zos_task_delay(5000);
	// 连接到onenet平台 
	extern void demo_onenet(void);
	demo_onenet();
	
	// 释放信号量，开始发送串口命令，读取串口数据
	zos_sem_post(notify_sem1);
	//连接到ctiot平台,就是电信的ctwing平台，详见demo_ctwing.c
	// extern void ctiot_init(void);
	// ctiot_init();
	user_main_task_Handle=ZOS_NULL;
	zos_task_exit();
}

// bad码转int
int decimal_bcd_code(unsigned char bcd)
{
 unsigned char Decimal;
 Decimal=bcd>>4;
 return (int)(Decimal=Decimal*10+(bcd&=0x0F));
}

// 串口2回调函数，读取串口数据，并转为float类型，上报到onenet
void callback(zos_uint8_t *rev_data, zos_uint16_t len)
{
	char *str_out = ZOS_NULL;
	sum = 0.0;
	cur = 0.0;
	str_out = zos_zalloc(200);

	for (int i = 0; i < len; i++)
	{
		zos_printf("no. %d val: %x\r\n", i, rev_data[i]);
	}

	if (len >= 11)
	{
		sum += decimal_bcd_code(rev_data[3]) * 100.0;
		sum += decimal_bcd_code(rev_data[4]) * 1.0;
		sum += decimal_bcd_code(rev_data[5]) * 0.01;
		sum += decimal_bcd_code(rev_data[6]) * 0.0001;

		cur += decimal_bcd_code(rev_data[7]) * 100.0;
		cur += decimal_bcd_code(rev_data[8]) * 1.0;
		cur += decimal_bcd_code(rev_data[9]) * 0.01;
		cur += decimal_bcd_code(rev_data[10]) * 0.0001;

		zos_printf("cur: %f, sum: %f\r\n", cur, sum);
	}

	zos_printf(str_out);
	zos_free(str_out);
	//上报数据到onenet
	cmiot_notify_with_ack(sum_object, strlen(rev_data), (cmiot_value_t)&sum, 0, 0);
	cmiot_notify_with_ack(cur_object, strlen(rev_data), (cmiot_value_t)&cur, 0, 0);
}

void send_uart_task(void *paramater)
{
	// 等待信号量，获取信号量以后开始执行
	zos_sem_wait(notify_sem1, ZOS_WAITING_FOREVER);
	// 读取水表示数
	zos_uint8_t hexdata[8] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x04, 0x44, 0x09};
	zos_task_delay(20000);
	while (1)
	{
		//向串口中发送指令
		zos_uart_write(ZOS_UART_BUS_2, hexdata, 8);
		zos_printf("uart cmd send...\r\n");
		zos_task_delay(1000 * SEND_INTERVAL);
	}
}

void uart2_task(void *parameter)
{
	ZOS_UART_CONFIG uart_cfg;
	uart_cfg.baud_rate = 9600;
	uart_cfg.data_bits = ZOS_UART_DATA_BITS_8;
	uart_cfg.parity = ZOS_UART_PARITY_NONE;
	uart_cfg.stop_bits = ZOS_UART_STOP_BITS_1;
	zos_uart_init(ZOS_UART_BUS_2, &uart_cfg, callback);
	uart2_Handle=ZOS_NULL;
	zos_task_exit();
}

int zos_main(void)
{
	//创建信号量
	notify_sem1 = zos_sem_create(0xffff,0);
	//如需调整shell口波特率，请调用此函数,最高可设置921600，默认不调用，波特率即115200
	//shell_uart_set_baud_rate(9600);
	//创建用户任务，注意任务的Priority 优先级不能全部设置为同一个等级，自己后期创建的任务需要根据任务的情况适当的降低或者提高优先级。
	user_main_task_Handle = zos_task_create ("user_main_task",user_main_task,ZOS_NULL,USER_MAIN_STACK_SIZE,task_Priority_BelowNormal);
	send_uart_cmd_Handle = zos_task_create("send_uart_task", send_uart_task, ZOS_NULL,USER_MAIN_STACK_SIZE,task_Priority_BelowNormal);
	uart2_Handle = zos_task_create("uart2_task", uart2_task, ZOS_NULL,USER_MAIN_STACK_SIZE,task_Priority_High);
}


